home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 August: Tool Chest / Dev.CD Aug 98 TC.toast / Tool Chest / QuickDraw / Bitblitz 1.0 / Source / BitBlitz.c next >
Encoding:
C/C++ Source or Header  |  1990-10-09  |  51.4 KB  |  1,830 lines  |  [TEXT/MPS ]

  1. /*--------------------------------------------------------------------------------------
  2. //
  3. //    File:          BitBlitz.c
  4. //
  5. //    Contents:    This files contains all of the main routines that comprise the BitBlitz tool.
  6. //                The tool was designed to be a learning/testing tool for the Copybits(), CopyMask(),
  7. //                and CopyDeepMask() QuickDraw calls.  It makes extensive use of GWorlds as well as
  8. //                the above mentioned QuickDraw bit tools.
  9. //
  10. //
  11. //    By Georgiann ("George") Delaney
  12. //    © 1989 - 1990, Apple Computer, Inc.
  13. //
  14. //--------------------------------------------------------------------------------------*/
  15.   
  16.   
  17. #include "MacHeaders.h"
  18.  
  19. #include "WCenter.h"
  20. #include "ColorTools.h"
  21.  
  22. #include "MainStuff.h"
  23.  
  24. #include "BlendUtils.h"
  25. #include "OffscreenUtils.h"
  26. #include "PICTUtils.h"
  27. #include "AlertDlogUtils.h"
  28. #include "AlrtDlogTools.h"
  29.  
  30. #include "BitBlitz.h"
  31.  
  32.  
  33.  
  34. #pragma segment CopyTests
  35.  
  36.  
  37. /*--------------------------------------------------------------------------------------*/
  38. /*  Constants  */
  39.  
  40. #define  AttrbDlogID        300                /*  Attributes dialog constants  */
  41. #define  diDlogTitle        3
  42. #define  diLine1            4
  43. #define  diLine2              5
  44. #define  diLine3            10
  45. #define  diLine4            16
  46. #define  diBitmapButton        6
  47. #define  diGWorldButton        7
  48. #define     diDepthPopUp        8
  49. #define     diContentPopUp        9
  50. #define     diHeightText        14
  51. #define     diWidthText        15
  52.  
  53. #define  TrapDlogID            301                /*  Trap selection dialog contents  */
  54. #define     diTrapLine1         4
  55. #define  diTrapLine2         5
  56. #define  diCopyMaskButton     6
  57. #define  diCopyDeepButton       7
  58. #define  diCopyBitsButton     8
  59.  
  60. #define  Sys7DlogID            302                /*  Need 7.0 dialog constants  */
  61. #define  AboutBoxDlogID        303                
  62.  
  63.  
  64. #define  kDepthMenu            300                /*  Attributes dialog menu constants  */
  65. #define  kContentMenu        301    
  66.  
  67.         
  68. #define  kNone                0                /*  Buffer type constants  */
  69. #define  kBitMap            1
  70. #define  kPixMap            2
  71. #define  kGWorld            3
  72.     
  73. #define     km1bpp                1                /*  Constants for depth menu selecions  */ 
  74. #define     km2bpp                2
  75. #define     km4bpp                3
  76. #define     km8bpp                4
  77. #define     km16bpp            5
  78. #define     km32bpp            6
  79. #define     kmMaxbpp            8
  80. #define  kTitleStrings        4000            /*  String resource constants  */
  81.  
  82. #define  kErrorStrings        4001
  83. #define        kBootMemErr           1
  84. #define        kDepthMemErr       2
  85. #define        kResizeMemErr     3
  86. #define        kPICTReadErr       4
  87. #define  kAttribDlogStrings    4002
  88.  
  89.  
  90. #define    kHLSRectBlend        1                
  91. #define    kHLSHBlend            2
  92. #define    kHLSVBlend            3
  93. #define    kGrayRectBlend        5
  94. #define    kGrayHBlend            6
  95. #define    kGrayVBlend         7
  96. #define    kGrayPatRectBlend     9
  97. #define    kGrayPatHBlend        10
  98. #define    kGrayPatVBlend        11
  99. #define    kSolidRGB            13
  100. #define    kPICT                15
  101.  
  102.  
  103.  
  104.  
  105. /*--------------------------------------------------------------------------------------*/
  106. /*  Global Variables  */
  107.  
  108. RGBColor    gLastRGB;                /* The last RGB Color selected for a solid fill.                  
  109.                                        Used as a starting color for the color picker for selection. */
  110. Point        gZeroPt;                /* Its just what you think - a point initialized to (0,0)       */ 
  111.  
  112.                                     /* Array containing the 8 standard colors    */
  113. long        gColorArray[8]    =  {blackColor, whiteColor, redColor, greenColor, blueColor, cyanColor, magentaColor, yellowColor};    
  114.  
  115.                                     /* Array containing rgb equivalents of 8 standard colors & gray*/
  116. RGBColor    gRGBArray[9];        
  117.  
  118. /*======================================================================================*/
  119. /*  Initialization Routines        */
  120.  
  121.  
  122. /*--------------------------------------------------------------------------------------*/
  123. Boolean myTrapAvailable(theNumber,theType)
  124. /*
  125. //    This procedure tests to see if the specified trap is available in the current system.
  126. */
  127.     short        theNumber;
  128.     TrapType    theType;
  129. {
  130.     return NGetTrapAddress(theNumber,theType) != GetTrapAddress(_Unimplemented);
  131.  
  132. /*--------------------------------------------------------------------------------------*/
  133. Boolean HasGWorlds()
  134. /*
  135. //    This procedure tests to see if the GWorlds are available.
  136. */
  137. {
  138.     #define _GWorldDispatch (short)0xAB1D
  139.  
  140.     return(myTrapAvailable(_GWorldDispatch,ToolTrap));
  141.  
  142.  
  143. /*--------------------------------------------------------------------------------------*/
  144. void InitTestGlobals()
  145. /*
  146. //    This procedure is called during the program's initialization to set the initial values
  147. //    of the app's constants.
  148. */
  149. {
  150.     gColorAvail   = HasColorQD();
  151.     gGWorldsAvail = HasGWorlds();
  152.     gZeroPt.h      = gZeroPt.v  = 0;
  153. }
  154.  
  155.  
  156. /*--------------------------------------------------------------------------------------*/
  157. void  InitTestWindowAttributes()
  158. /*
  159. //    InitTestWindowAttributes() performs initialization of the global structs defining the  
  160. //    attributes of the source, mask, and destination bit images.
  161. */
  162. {
  163.     register    i;
  164.     
  165.             /*  initialize all of the common fields  */
  166.     for (i=kSrcWindow; i <= kBitWindow; i++)  {
  167.         gWList[i].window            = nil;
  168.         gWList[i].buffer.gworld        = nil;
  169.         
  170.         if (gGWorldsAvail)  {
  171.             gWList[i].bufferType    = kGWorld;
  172.             gWList[i].bufferDepth    = 0;
  173.             }
  174.         else  {
  175.             gWList[i].bufferType    = kBitMap;
  176.             gWList[i].bufferDepth    = 1;
  177.             }
  178.         }
  179.  
  180.             /*  set initial window contents with respect to the availability of color.  */
  181.     if (gColorAvail)  {
  182.         gWList[kSrcWindow].contentType            = kHLSRectBlend;
  183.         gWList[kSrcWindow].content.saturation    = 65535;
  184.     
  185.         gWList[kMskWindow].contentType            = kGrayVBlend;
  186.     
  187.         gWList[kDstWindow].contentType            = kSolidRGB;
  188.         gWList[kDstWindow].content.RGB.red        = 0xFFFF;
  189.         gWList[kDstWindow].content.RGB.green     = 0xFFFF;
  190.         gWList[kDstWindow].content.RGB.blue        = 0x0000;
  191.         }
  192.     else  {
  193.         gWList[kSrcWindow].contentType            = kGrayPatRectBlend;
  194.         gWList[kMskWindow].contentType            = kGrayPatVBlend;
  195.         gWList[kDstWindow].contentType            = kGrayPatHBlend;
  196.         }
  197. }
  198.  
  199.  
  200. /*--------------------------------------------------------------------------------------*/
  201. void  InitColorSettings()
  202. /*
  203. //    InitColorSettings() initializes the values in the color array.
  204. */
  205. {
  206.     gRGBArray[0].red   = 0x0000;    gRGBArray[0].green = 0x0000;    gRGBArray[0].blue  = 0x0000;
  207.     gRGBArray[1].red   = 0xFFFF;    gRGBArray[1].green = 0xFFFF;    gRGBArray[1].blue  = 0xFFFF;
  208.     gRGBArray[2].red   = 0xDD6B;    gRGBArray[2].green = 0x08C2;    gRGBArray[2].blue  = 0x06A2;
  209.     gRGBArray[3].red   = 0x0000;    gRGBArray[3].green = 0x8000;    gRGBArray[3].blue  = 0x11B0;
  210.     gRGBArray[4].red   = 0x0000;    gRGBArray[4].green = 0x0000;    gRGBArray[4].blue  = 0xD400;
  211.     gRGBArray[5].red   = 0x0241;    gRGBArray[5].green = 0xAB54;    gRGBArray[5].blue  = 0xEAFF;
  212.     gRGBArray[6].red   = 0xF2D7;    gRGBArray[6].green = 0x0856;    gRGBArray[6].blue  = 0x84EC;
  213.     gRGBArray[7].red   = 0xFC00;    gRGBArray[7].green = 0xF37D;    gRGBArray[7].blue  = 0x052F;
  214.     gRGBArray[8].red   = 0x7FFF;    gRGBArray[8].green = 0x7FFF;    gRGBArray[8].blue  = 0x7FFF;
  215.  
  216.  
  217.     gFGColor.menuIndex         = kBlack;
  218.     gFGColor.rgb            = gRGBArray[kBlack-1];
  219.     
  220.     gBKColor.menuIndex         = kWhite;
  221.     gBKColor.rgb            = gRGBArray[kWhite-1];
  222.  
  223.     gOPColor.menuIndex        = kGray;
  224.     gOPColor.rgb            = gRGBArray[kGray-1];
  225.  
  226.     gHiliteColor.menuIndex    = kBlue;
  227.     gHiliteColor.rgb        = gRGBArray[kBlue-1];
  228. }
  229.  
  230. /*--------------------------------------------------------------------------------------*/
  231. void  InitRgnSettings()
  232. /*
  233. //    InitRgnSettings() initializes all of the region settings to nil.
  234. */
  235. {
  236.     register    i;
  237.     
  238.     for (i=kClpRgn; i<=kMskRgn; i++)  {
  239.         gRList[i].type = kNoRgn;
  240.         gRList[i].rgn  = nil;
  241.         }
  242. }
  243.  
  244.  
  245. /*--------------------------------------------------------------------------------------*/
  246. void  DisposeRgnSettings()
  247. /*
  248. //    DisposeRgnSettings() disposes any region settings that may have been set by the user.
  249. */
  250. {
  251.     register    i;
  252.     
  253.     for (i=kClpRgn; i<=kMskRgn; i++)  {
  254.         if (gRList[i].rgn != nil)  {
  255.             DisposeRgn(gRList[i].rgn);
  256.             gRList[i].rgn = nil;
  257.             }
  258.         }
  259. }
  260.  
  261.  
  262.  
  263. /*--------------------------------------------------------------------------------------*/
  264. void  MenuIndex2RGB(ColorAttributes colorSelect, RGBColor *theRGB)
  265. {
  266.     if (colorSelect.menuIndex == kCustomColor)
  267.         *theRGB = colorSelect.rgb;
  268.     else
  269.         *theRGB = gRGBArray[colorSelect.menuIndex-1];
  270. }
  271.  
  272.  
  273. /*--------------------------------------------------------------------------------------*/
  274. void  DrawOval()
  275. {
  276.     Rect    tempRect;
  277.  
  278.     tempRect = gWList[kBitWindow].window->portRect;
  279.     
  280.     InsetRect(&tempRect, 10, 10);
  281.     FrameOval(&tempRect);
  282. }
  283.  
  284. /*--------------------------------------------------------------------------------------*/
  285. void  DrawDiamond()
  286. {
  287.     Rect    tempRect;
  288.     Point    centerPt;
  289.  
  290.     tempRect = gWList[kBitWindow].window->portRect;
  291.     
  292.     InsetRect(&tempRect, 10, 10);
  293.     
  294.     centerPt.h = tempRect.left + ((tempRect.right  - tempRect.left)>>1);
  295.     centerPt.v = tempRect.top  + ((tempRect.bottom - tempRect.top )>>1);
  296.     
  297.     MoveTo(centerPt.h,        tempRect.top);
  298.     LineTo(tempRect.right,    centerPt.v);
  299.     LineTo(centerPt.h,        tempRect.bottom);
  300.     LineTo(tempRect.left,    centerPt.v);
  301.     LineTo(centerPt.h,        tempRect.top);
  302. }
  303.  
  304. /*--------------------------------------------------------------------------------------*/
  305. void  DrawHole()
  306. {
  307.     Rect    tempRect;
  308.  
  309.     tempRect = gWList[kBitWindow].window->portRect;
  310.     
  311.     InsetRect(&tempRect, 10, 10);
  312.     FrameOval(&tempRect);
  313.  
  314.     InsetRect(&tempRect, ((tempRect.right  - tempRect.left)>>2), ((tempRect.bottom - tempRect.top )>>2));
  315.     FrameOval(&tempRect);
  316. }
  317.  
  318.  
  319. /*--------------------------------------------------------------------------------------*/
  320. void  DrawStar()
  321. {
  322.     Rect    tempRect;
  323.     Point    centerPt;
  324.  
  325.     tempRect = gWList[kBitWindow].window->portRect;
  326.     
  327.     InsetRect(&tempRect, 10, 10);
  328.     
  329.     centerPt.h = tempRect.left + ((tempRect.right  - tempRect.left)>>1);
  330.     centerPt.v = tempRect.top  + ((tempRect.bottom - tempRect.top )/3);
  331.     
  332.     MoveTo(centerPt.h,        tempRect.top);
  333.     LineTo(tempRect.right,    tempRect.bottom);
  334.     LineTo(tempRect.left,    centerPt.v);
  335.     LineTo(tempRect.right,    centerPt.v);
  336.     LineTo(tempRect.left,    tempRect.bottom);
  337.     LineTo(centerPt.h,        tempRect.top);
  338. }
  339.  
  340.  
  341. /*--------------------------------------------------------------------------------------*/
  342. void  UpdateRgnSettings()
  343. /*
  344. //    UpdateRgnSettings() updates any region settings that the user has selected after the 
  345. //  corresponding window has been resized.
  346. */
  347. {
  348.     register    i;
  349.     
  350.     
  351.     DisposeRgnSettings();
  352.     
  353.     for (i=kClpRgn; i<=kMskRgn; i++) 
  354.  
  355.         if (gRList[i].type != kNoRgn)  {
  356.             gRList[i].rgn = NewRgn();
  357.             OpenRgn();
  358.     
  359.             switch(gRList[i].type)  {
  360.                 case kDiamondClip:    DrawDiamond();        break;
  361.                 case kOvalClip:        DrawOval();            break;
  362.                 case kStarClip:        DrawStar();            break;
  363.                 case kHoleClip:        DrawHole();            break;
  364.                 }
  365.     
  366.             CloseRgn(gRList[i].rgn);
  367.             }
  368. }
  369.  
  370.  
  371. /*--------------------------------------------------------------------------------------*/
  372. void  SetEnv()
  373. /*
  374. //    SetEnv() is called to set the color environment and clip regions the user haa designated
  375. //  for use in the copy call.
  376. */
  377. {
  378.     GrafPtr        thePort;
  379.     
  380.  
  381.     if (gColorAvail)  {
  382.         RGBForeColor(&gFGColor.rgb);
  383.         RGBBackColor(&gBKColor.rgb);
  384.         OpColor     (&gOPColor.rgb);
  385.         HiliteColor (&gHiliteColor.rgb);
  386.         }
  387.     else  {
  388.         ForeColor(gColorArray[gFGColor.menuIndex-1]);
  389.         BackColor(gColorArray[gBKColor.menuIndex-1]);
  390.         }
  391.     
  392.     if (gRList[kClpRgn].rgn != nil)  {
  393.         gHoldClpRgn = NewRgn();
  394.         GetClip(gHoldClpRgn);
  395.         SetClip(gRList[kClpRgn].rgn);
  396.         }
  397.  
  398.     if (gRList[kVisRgn].rgn != nil)  {
  399.         GetPort(&thePort);
  400.         gHoldVisRgn     = thePort->visRgn;
  401.         thePort->visRgn = gRList[kVisRgn].rgn;
  402.         }
  403. }
  404.  
  405.  
  406. /*--------------------------------------------------------------------------------------*/
  407. void  RestoreEnv()
  408. /*
  409. //    RestoreEnv() restores the color and clip settings following the copy call.
  410. */
  411. {
  412.     GrafPtr        thePort;
  413.     
  414.     if (gColorAvail)  {
  415.         RGBForeColor(&gRGBArray[kBlack-1]);
  416.         RGBBackColor(&gRGBArray[kWhite-1]);
  417.         }
  418.     else  {
  419.         ForeColor(gColorArray[kBlack-1]);
  420.         BackColor(gColorArray[kWhite-1]);
  421.         }
  422.         
  423.  
  424.     if (gHoldClpRgn != nil)  {
  425.         SetClip(gHoldClpRgn);
  426.         DisposeRgn(gHoldClpRgn);
  427.         gHoldClpRgn = nil;
  428.         }
  429.  
  430.     if (gHoldVisRgn != nil)  {
  431.         GetPort(&thePort);
  432.         thePort->visRgn     = gHoldVisRgn;
  433.         }
  434.             
  435. }
  436.  
  437.  
  438.  
  439. /*======================================================================================*/
  440. /*  Routines to handle CopyMode selection    */
  441.  
  442.  
  443. /*--------------------------------------------------------------------------------------*/
  444. short  ModeMenuItem2CopyMode(short theItem)
  445. /*
  446. //  This routine is used to convert a copy mode menu selection to an actual QuickDraw 
  447. //  copy mode.   The reason a switch statement is required here is because the 
  448. //    QuickDraw copy mode constants are not contiguous.
  449. */
  450. {
  451.     short    theMode;
  452.     
  453.     switch(theItem)  {
  454.         case kSrcCopy:        if (gDither) 
  455.                                   theMode = ditherCopy;
  456.                             else theMode = theItem -1;        
  457.                             break;
  458.         case kSrcOr:
  459.         case kSrcXor:
  460.         case kSrcBic:
  461.         case kNotSrcCopy:
  462.         case kNotSrcOr:
  463.         case kNotSrcXor:
  464.         case kNotSrcBic:    theMode = theItem -1;        break;
  465.  
  466.         case kBlend:        theMode = blend;            break;
  467.         case kAddPin:        theMode = addPin;            break;
  468.         case kAddOver:        theMode = addOver;            break;
  469.         case kAddMax:        theMode = addMax;            break;
  470.         case kAddMin:        theMode = adMin;            break;
  471.         case kSubOver:        theMode = subOver;            break;
  472.         case kSubPin:        theMode = subPin;            break;
  473.         
  474.         case kTransparent:    theMode = transparent;        break;
  475.         
  476.         case kHilite:        theMode = hilite;            break;
  477.         }
  478.     
  479.     return(theMode);
  480. }
  481.  
  482.  
  483. /*--------------------------------------------------------------------------------------*/
  484. short  CopyMode2ModeMenuItem(short theMode)
  485. /*
  486. //  This routine is used to convert a QuickDraw copy mode to a copy mode menu selection.
  487. //  The reason a switch statement is required here is because the QuickDraw copy mode
  488. //  constants are not contiguous.
  489. */
  490. {
  491.     short  theItem;
  492.     
  493.     switch(theMode)  {
  494.         case ditherCopy:    theItem = srcCopy +1;         break;
  495.         
  496.         case srcCopy:
  497.         case srcOr:
  498.         case srcXor:
  499.         case srcBic:
  500.         case notSrcOr:
  501.         case notSrcCopy:
  502.         case notSrcXor:
  503.         case notSrcBic:        theItem = theMode +1;        break;
  504.  
  505.         case blend:            theItem = kBlend;            break;
  506.         case addPin:        theItem = kAddPin;            break;
  507.         case addOver:        theItem = kAddOver;            break;
  508.         case adMin    :        theItem = kAddMin;            break;
  509.         case addMax:        theItem = kAddMax;            break;
  510.         case subOver:        theItem = kSubOver;            break;
  511.         case subPin:        theItem = kSubPin;            break;
  512.         
  513.         case transparent:    theItem = kTransparent;        break;
  514.         
  515.         case hilite:        theItem = kHilite;            break;
  516.         }
  517.         
  518.     return(theItem);
  519. }
  520.  
  521.   
  522.   
  523. /*======================================================================================*/
  524. /*  Window Attribute PICT handle cleanup.    */
  525.  
  526.  
  527. /*--------------------------------------------------------------------------------------*/
  528. void  DisposePICTInfo(short windowCode)
  529. /*    
  530. //    DisposePICTInfo() tests to determine if the specified window has a PICT handle allocated 
  531. //    for buffer updating and disposes it if it is not already nil.
  532. */
  533. {
  534.     if ((gWList[windowCode].contentType == kPICT) && (gWList[windowCode].content.pictInfo != nil))  {
  535.         DisposHandle((Handle)gWList[windowCode].content.pictInfo);
  536.         gWList[windowCode].content.pictInfo = nil;
  537.         }
  538. }
  539.  
  540.  
  541.  
  542. /*======================================================================================*/
  543. /*  Offscreen Buffer Maintainance Routines     */
  544.  
  545.  
  546. /*--------------------------------------------------------------------------------------*/
  547. Boolean  CreateWindowBuffer(short windowCode)
  548. /*    
  549. //    CreateWindowBuffer() creates an offscreen buffer of the designated size with respect to the
  550. //    attributes set in the window's attribute information.
  551. */
  552. {
  553.     Boolean        bufferCreated    = false;
  554.     
  555.     switch(gWList[windowCode].bufferType) {
  556.         case kBitMap:    
  557.             bufferCreated = CreateOSBitmap(&gWList[windowCode].buffer.bitmap, &gWList[windowCode].window->portRect);
  558.             break;
  559.         case kGWorld:                
  560.             bufferCreated = (NewGWorld(&gWList[windowCode].buffer.gworld, gWList[windowCode].bufferDepth, &gWList[windowCode].window->portRect, nil, nil, 0) == noErr);
  561.             break;
  562.         }
  563.     
  564.     return(bufferCreated);
  565. }
  566.  
  567.  
  568. /*--------------------------------------------------------------------------------------*/
  569. Boolean  UpdateWindowBuffer(short windowCode, short depth)    
  570. /* 
  571. //    This routine updates the specified window's offscreen buffer to the desired depth.
  572. */
  573. {
  574.     Boolean  bufferChanged  = false;
  575.     long     gwError;
  576.     
  577.     if (gWList[windowCode].bufferType == kGWorld) {    
  578.         gWList[windowCode].bufferDepth = depth;
  579.         
  580.         gwError = (UpdateGWorld(&gWList[windowCode].buffer.gworld, depth, &gWList[windowCode].buffer.gworld->portRect, 0, 0, 0) == noErr);
  581.         bufferChanged = (gwError & gwFlagErr);
  582.         }
  583.         
  584.     return(true);
  585. }
  586.  
  587.  
  588. /*--------------------------------------------------------------------------------------*/
  589. void  DisposeWindowBuffer(short windowCode)
  590. /*    
  591. //    DisposeWindowBuffer() determines the type of buffer that is associated with the specified 
  592. //    window and performs the appropriate dispose.
  593. */
  594. {
  595.     if (gWList[windowCode].buffer.gworld != nil) 
  596.         switch(gWList[windowCode].bufferType) {
  597.             case kBitMap:    DisposeOSBitmap(gWList[windowCode].buffer.bitmap);    break;
  598.             case kGWorld:    DisposeGWorld  (gWList[windowCode].buffer.gworld);    break;
  599.             }
  600. }
  601.  
  602.  
  603. /*--------------------------------------------------------------------------------------*/
  604. Boolean  SetOffscreen(short windowCode, short type, short depth)    
  605. /*
  606. //    Hey, guess what, it does what you expect - sets the specified window's buffer to the
  607. //  specified offscreen type and depth.
  608. */
  609. {
  610.     Boolean        bufferChanged     = false;    
  611.  
  612.             
  613.     if (type != gWList[windowCode].bufferType) {
  614.         DisposeWindowBuffer(windowCode);
  615.         
  616.         gWList[windowCode].bufferType  = type;
  617.         gWList[windowCode].bufferDepth = depth;
  618.         bufferChanged = CreateWindowBuffer(windowCode);
  619.         if (!bufferChanged)
  620.             OKRsrcAlert(kErrorStrings,kDepthMemErr);
  621.         }
  622.     else  {
  623.         if (depth != gWList[windowCode].bufferDepth)  {
  624.             gWList[windowCode].bufferDepth = depth;
  625.             bufferChanged = UpdateWindowBuffer(windowCode, depth);
  626.             if (!bufferChanged)
  627.                 OKRsrcAlert(kErrorStrings,kDepthMemErr);
  628.             }
  629.         }
  630.     
  631.     return(bufferChanged);
  632. }
  633.  
  634.  
  635. /*--------------------------------------------------------------------------------------*/
  636. Boolean  UpdateOffscreen(short windowCode, short type, short depth)
  637. /*
  638. //    UpdateOffscreen() tests to determine if the specified window's offscreen buffer has the 
  639. //  specified type and depth attributes and  performs whatever buffer updating necessary.
  640. */
  641. {
  642.     Boolean    depthChanged = false;
  643.     
  644.  
  645.     depthChanged = SetOffscreen(windowCode,type,depth);
  646.     
  647.                 /*  Since the dest and copy window must be the same depth, if the user changes 
  648.                 //    the depth of the dest window, the copy window should also be set to the 
  649.                 //  new selected depth/
  650.                 */
  651.     if ((depthChanged) && (windowCode == kDstWindow))  {
  652.         depthChanged = SetOffscreen(kBitWindow,type,depth);
  653.             
  654.                 /*  However, if an error occurs and the copy window can not be set to the
  655.                 //  new depth then return the dest window to the original depth so that both are
  656.                 //  equal.
  657.                 */
  658.         if (!depthChanged) 
  659.             SetOffscreen(kDstWindow,gWList[kBitWindow].bufferType,gWList[kBitWindow].bufferDepth);
  660.         }
  661.         
  662.     if (depthChanged)  {
  663.         DrawBuffer(windowCode);
  664.         DrawBuffer(kBitWindow);
  665.         }
  666.                 
  667.     return(depthChanged);
  668. }
  669.  
  670.  
  671.  
  672. /*======================================================================================*/
  673. /*  Attributes Dialog Routines     */
  674.  
  675.  
  676. /*--------------------------------------------------------------------------------------*/
  677. void  SetDepthMenuSelection(DialogPtr  theDlog, short  theItem, short theDepth)
  678. /*
  679. //    This procedure initializes the attributes dialog's depth popup to the depth of the 
  680. //    selected window's offscreen depth.
  681. */
  682. {
  683.     short        itemType;
  684.     Handle        itemHdl;
  685.     Rect        itemRect;
  686.     
  687.     short        selection;
  688.     MenuHandle    depthMenuHdl;
  689.  
  690.     
  691.     depthMenuHdl = GetMHandle(kDepthMenu);
  692.     if ((!gGWorldsAvail) || (!gColorAvail))  {
  693.         DisableItem(depthMenuHdl, km2bpp);
  694.         DisableItem(depthMenuHdl, km4bpp);
  695.         DisableItem(depthMenuHdl, km8bpp);
  696.         DisableItem(depthMenuHdl, km16bpp);
  697.         DisableItem(depthMenuHdl, km32bpp);
  698.         }
  699.         
  700.     if (!gGWorldsAvail)  
  701.         DisableItem(depthMenuHdl, kmMaxbpp);
  702.  
  703.     GetDItem(theDlog,theItem,&itemType,&itemHdl,&itemRect);
  704.     
  705.     switch(theDepth)  {   
  706.         case 1    : selection = km1bpp;    break;
  707.         case 2    : selection = km2bpp;    break;
  708.         case 4    : selection = km4bpp;    break;
  709.         case 8    : selection = km8bpp;    break;
  710.         case 16    : selection = km16bpp;    break;
  711.         case 32    : selection = km32bpp;    break;
  712.         case 0    : selection = kmMaxbpp;    break;
  713.         }
  714.     
  715.     SetCtlValue((ControlHandle)itemHdl,selection);
  716. }
  717.  
  718.  
  719. /*--------------------------------------------------------------------------------------*/
  720. short  GetDepthMenuSelection(DialogPtr  theDlog, short  theItem)
  721. /*
  722. //    This procedure converts the attributes dialog's depth popup selection to its
  723. //    equivalent depth value.
  724. */
  725. {
  726.     short        itemType;
  727.     Handle        itemHdl;
  728.     Rect        itemRect;
  729.     
  730.     short        selection,depth;
  731.  
  732.  
  733.     GetDItem(theDlog,theItem,&itemType,&itemHdl,&itemRect);
  734.     selection = GetCtlValue((ControlHandle)itemHdl);
  735.     
  736.     switch(selection)  {   
  737.         case km1bpp     : depth = 1;    break;
  738.         case km2bpp     : depth = 2;    break;
  739.         case km4bpp     : depth = 4;    break;
  740.         case km8bpp     : depth = 8;    break;
  741.         case km16bpp : depth = 16;    break;
  742.         case km32bpp : depth = 32;    break;
  743.         case kmMaxbpp: depth = 0;    break;
  744.         }
  745.     
  746.     return(depth);
  747. }
  748.  
  749.  
  750. /*--------------------------------------------------------------------------------------*/
  751. void  SetContentMenuSelection(DialogPtr  theDlog, short  theItem, short theContent)
  752. /*
  753. //    This procedure initializes the attributes dialog's content popup to reflect the 
  754. //    selected window's current content type.
  755. */
  756. {
  757.     short        itemType;
  758.     Handle        itemHdl;
  759.     Rect        itemRect;
  760.     MenuHandle    contentMenuHdl;
  761.  
  762.     contentMenuHdl = GetMHandle(kContentMenu);
  763.     if (!gColorAvail)  {
  764.         DisableItem(contentMenuHdl, kHLSRectBlend);
  765.         DisableItem(contentMenuHdl, kHLSHBlend);
  766.         DisableItem(contentMenuHdl, kHLSVBlend);
  767.         DisableItem(contentMenuHdl, kGrayRectBlend);
  768.         DisableItem(contentMenuHdl, kGrayHBlend);
  769.         DisableItem(contentMenuHdl, kGrayVBlend);
  770.         DisableItem(contentMenuHdl, kSolidRGB);
  771.         }
  772.  
  773.     GetDItem(theDlog,theItem,&itemType,&itemHdl,&itemRect);
  774.     SetCtlValue((ControlHandle)itemHdl,theContent);
  775. }
  776.  
  777.  
  778. /*--------------------------------------------------------------------------------------*/
  779. short  GetContentMenuSelection(DialogPtr  theDlog, short  theItem)
  780. /*
  781. //    This procedure returns the attributes dialog's content popup selection.
  782. */
  783. {
  784.     short        itemType;
  785.     Handle        itemHdl;
  786.     Rect        itemRect;
  787.  
  788.  
  789.     GetDItem(theDlog,theItem,&itemType,&itemHdl,&itemRect);
  790.     return(GetCtlValue((ControlHandle)itemHdl));
  791. }
  792.  
  793.  
  794. /*--------------------------------------------------------------------------------------*/
  795. pascal Boolean AttrbDlogFilter(DialogPtr theDlog, EventRecord *theEvent, short *theItem)
  796. {
  797.  /*
  798.  //  AttrbDlogFilter() is the dialog filter for the attributes  dialog.
  799.  */
  800.  
  801.                  
  802.     IBeamCursorAdjust(theDlog,(ValidTextProcPtr)StdValidDecTextProc);
  803.  
  804.                 /*  If we get a key down event, check to see if it is for the OK or Cancel
  805.                 //  buttons.  If not, filter it for numeric input only (via EditNumText()).
  806.                 */
  807.     if ((theEvent->what == autoKey) || (theEvent->what == keyDown))  {
  808.         short editItem = ((DialogPeek)theDlog)->editField + 1;
  809.         
  810.         if (HandleOkayCancel(theDlog,theEvent,theItem))
  811.             return(true);
  812.  
  813.         EditNumText(theDlog,theEvent,editItem,0L,1000L,decimalOnly);
  814.         }
  815.         
  816.     return(false);
  817. }
  818.  
  819.  
  820. /*--------------------------------------------------------------------------------------*/
  821. Boolean  ChangeWindowAttributes(short windowCode)
  822. /*
  823. //    ChangeWindowAttributes() allows the user to change any of the attributes of the source, 
  824. //  mask, or destination windows.
  825. //
  826. //  This dialog is accessed by selecting the appropriate menu selection or by double-clicking 
  827. //  in the content region of the desired window.
  828. */
  829. {
  830.     DialogPtr    theDlog;
  831.     GrafPtr        holdPort;
  832.     short        itemHit;
  833.     
  834.     Boolean        okHit            = false;
  835.     Boolean        done            = false;
  836.     Boolean        bufferChanged    = false;
  837.     Boolean        contentChanged    = false;
  838.  
  839.     short        tempBufferType   = gWList[windowCode].bufferType;
  840.     short        tempBufferDepth  = gWList[windowCode].bufferDepth;
  841.     short        tempContentType  = gWList[windowCode].contentType;
  842.     PicHandle    tempPICT         = nil;  
  843.     short        tempSaturation     = 65535;  
  844.     RGBColor    tempRGB;
  845.     
  846.     register     i;
  847.     short        contentSelect;
  848.     SFReply        reply;
  849.     Str255        tempStr;
  850.     
  851.     Point        oldDimen, newDimen;
  852.     
  853.     
  854.                 /*  Initialize temporary values that have not already been initialized during
  855.                 //    variable declaration.
  856.                 */
  857.     if (tempContentType == kSolidRGB) 
  858.         tempRGB = gWList[windowCode].content.RGB;
  859.     else
  860.         tempRGB = gLastRGB;
  861.  
  862.             
  863.                 /*  Allocate and center the dialog  */
  864.     CenterWRsrc(DLOG,AttrbDlogID,vThird);
  865.     theDlog = GetNewDialog(AttrbDlogID, nil, (WindowPtr)-1);
  866.     
  867.     reply.good = false;
  868.     
  869.                 /*  If the dialog has been allocated successfully - process the user's selections  */
  870.     if (theDlog != nil)  {
  871.     
  872.                 /*  Save off the current port.  */
  873.         GetPort(&holdPort);
  874.         SetPort(theDlog);
  875.         
  876.                 /*  Dialog item initialization.  */
  877.         SetDlogItemProc(theDlog,diLine1,(ProcPtr)FrameDlogItemRect);
  878.         SetDlogItemProc(theDlog,diLine2,(ProcPtr)FrameDlogItemRect);
  879.         SetDlogItemProc(theDlog,diLine3,(ProcPtr)FrameDlogItemRect);
  880.         SetDlogItemProc(theDlog,diLine4,(ProcPtr)FrameDlogItemRect);
  881.         
  882.                 /*  Set the appropriate dialog title  */
  883.           GetIndString (tempStr,kAttribDlogStrings,windowCode+1);
  884.           SetDlogString(theDlog, diDlogTitle, tempStr);
  885.  
  886.         HandleRadioButtons(theDlog,diBitmapButton,diGWorldButton,((tempBufferType == kGWorld) ? diGWorldButton : diBitmapButton));
  887.         SetDepthMenuSelection  (theDlog, diDepthPopUp,  tempBufferDepth);
  888.         SetContentMenuSelection(theDlog, diContentPopUp,tempContentType);
  889.  
  890.         oldDimen.v = gWList[windowCode].window->portRect.bottom - gWList[windowCode].window->portRect.top;
  891.         oldDimen.h = gWList[windowCode].window->portRect.right  - gWList[windowCode].window->portRect.left;
  892.  
  893.         SetDlogShort(theDlog,diHeightText,oldDimen.v);
  894.         SetDlogShort(theDlog,diWidthText, oldDimen.h);
  895.         SelIText    (theDlog,diHeightText, 0, 32767);
  896.     
  897.                 /*  Display the dialog  */
  898.         ShowWindow(theDlog);
  899.         
  900.                 /*  Process the user's actions  */
  901.         do  {
  902.             ModalDialog((ProcPtr)AttrbDlogFilter, &itemHit);
  903.             
  904.             switch (itemHit)  {
  905.                     case  ok:                okHit = true;        
  906.                     case  cancel:            done  = true;
  907.                                             break;
  908.                 
  909.                     case  diBitmapButton:     HandleRadioButtons(theDlog,diBitmapButton,diGWorldButton,itemHit);
  910.                                             tempBufferDepth = 1;
  911.                                             tempBufferType  = kBitMap;
  912.                                             break;
  913.                                             
  914.                     case  diDepthPopUp:
  915.                     case  diGWorldButton:    HandleRadioButtons(theDlog,diBitmapButton,diGWorldButton,diGWorldButton);
  916.                                             tempBufferDepth = GetDepthMenuSelection(theDlog, diDepthPopUp);
  917.                                             tempBufferType  = kGWorld;
  918.                                             break;
  919.                 
  920.     
  921.                     case  diContentPopUp:    contentSelect = GetContentMenuSelection(theDlog, diContentPopUp);
  922.                                         
  923.                                             switch(contentSelect) {
  924.                                                 case kSolidRGB :     
  925.                                                         GetColor(gZeroPt,"\pSelect a color.",&tempRGB,&tempRGB);
  926.                                                         tempContentType = contentSelect;
  927.                                                         for(i=kSrcWindow; i <= kBitWindow; i++)
  928.                                                             DrawWindow(i);
  929.                                                         break;
  930.                                                 
  931.                                                 case kPICT:    
  932.                                                         StdGetPictFile(&reply);
  933.                                                         for(i=kSrcWindow; i <= kBitWindow; i++)
  934.                                                             DrawWindow(i);
  935.                                                         if (reply.good)
  936.                                                             tempContentType = contentSelect;
  937.                                                         break;
  938.                                                         
  939.                                                 default:  tempContentType = contentSelect;
  940.                                                 }
  941.                                             break;
  942.                     }
  943.             }  while ( !done );
  944.  
  945.         GetDlogShort(theDlog,diHeightText, &newDimen.v);
  946.         GetDlogShort(theDlog,diWidthText,  &newDimen.h);
  947.         
  948.         if (newDimen.v < 2)  newDimen.v = 2;
  949.         if (newDimen.h < 2)  newDimen.h = 2;
  950.         
  951.         DisposDialog(theDlog);
  952.         SetPort(holdPort);
  953.         }
  954.         
  955.     if (okHit) {
  956.         SetCursor(*GetCursor(watchCursor));
  957.         
  958.         for(i=kSrcWindow; i <= kBitWindow; i++)
  959.             DrawWindow(i);
  960.             
  961.                 /* Reset the offscreen depth if it has been changed  */
  962.         bufferChanged = UpdateOffscreen(windowCode, tempBufferType, tempBufferDepth);
  963.             
  964.                 
  965.                 /* Reset the content region if a new type has been selected */
  966.         if ((tempContentType != gWList[windowCode].contentType) ||
  967.             (tempContentType == kPICT) || (tempContentType == kSolidRGB)) {
  968.             if (tempContentType == kPICT) {
  969.                 if (ReadPICTFile(&reply, &tempPICT) == noErr) {
  970.                     if (gWList[windowCode].contentType == kPICT)
  971.                         DisposePICTInfo(windowCode);
  972.                     gWList[windowCode].contentType         = kPICT;
  973.                     gWList[windowCode].content.pictInfo  = tempPICT;
  974.                     DrawBuffer(windowCode);
  975.                     contentChanged = true;
  976.                     }
  977.                 else
  978.                     if (reply.good)
  979.                         OKRsrcAlert(kErrorStrings,kPICTReadErr);
  980.                 }
  981.             else  {
  982.                 if (gWList[windowCode].contentType == kPICT)
  983.                     DisposePICTInfo(windowCode);
  984.                     
  985.                 gWList[windowCode].contentType = tempContentType;
  986.                 
  987.                 switch(tempContentType)  {
  988.                     case kSolidRGB:     gWList[windowCode].content.RGB = gLastRGB = tempRGB;      break;
  989.                     case kHLSRectBlend: 
  990.                     case kHLSHBlend:     
  991.                     case kHLSVBlend:     gWList[windowCode].content.saturation = tempSaturation;    break;
  992.                     }
  993.                     
  994.                 DrawBuffer(windowCode);
  995.                 contentChanged = true;
  996.                 }
  997.             }
  998.         
  999.  
  1000.                 /*  Resize the window if the size has been altered.  Remember, the source and 
  1001.                 //  mask windows (when available)  as well as the destination and copy windows
  1002.                 //  must be the same size so if one is altered its corresponding window must also
  1003.                 //  be sized.  It therefore follows that if there is not enough memory available to
  1004.                 //  enlarge both windows then neither should be changed.  
  1005.                 */
  1006.         if ( !EqualPt(oldDimen, newDimen) )  {
  1007.             GetPort(&holdPort);
  1008.             
  1009.             if ((windowCode == kSrcWindow) || (windowCode == kMskWindow)) {
  1010.                 SetPort(gWList[kSrcWindow].window);
  1011.                 if (ResizeTestWindow(&newDimen,kSrcWindow)) { 
  1012.                     oldDimen.h = gWList[kSrcWindow].window->portRect.right  - gWList[kSrcWindow].window->portRect.left;
  1013.                     oldDimen.v = gWList[kSrcWindow].window->portRect.bottom - gWList[kSrcWindow].window->portRect.top;
  1014.     
  1015.                     SetPort(gWList[kMskWindow].window);
  1016.                     if (ResizeTestWindow(&newDimen,kMskWindow))  {
  1017.                         SizeWindow(gWList[kMskWindow].window,newDimen.h,newDimen.v,false);
  1018.                         SizeWindow(gWList[kSrcWindow].window,newDimen.h,newDimen.v,false);
  1019.                         }
  1020.                     else {
  1021.                         SetPort(gWList[kSrcWindow].window);
  1022.                         ResizeTestWindow(&oldDimen,kSrcWindow);
  1023.                         }
  1024.                     }
  1025.                 }
  1026.     
  1027.             if ((windowCode == kDstWindow) || (windowCode == kBitWindow)) {
  1028.                 SetPort(gWList[kDstWindow].window);
  1029.                 if (ResizeTestWindow(&newDimen,kDstWindow))  {
  1030.                     oldDimen.h = gWList[kDstWindow].window->portRect.right  - gWList[kDstWindow].window->portRect.left;
  1031.                     oldDimen.v = gWList[kDstWindow].window->portRect.bottom - gWList[kDstWindow].window->portRect.top;
  1032.                     
  1033.                     SetPort(gWList[kBitWindow].window);
  1034.                     if (ResizeTestWindow(&newDimen,kBitWindow))  {
  1035.                         SizeWindow(gWList[kBitWindow].window,newDimen.h,newDimen.v,false);
  1036.                         SizeWindow(gWList[kDstWindow].window,newDimen.h,newDimen.v,false);
  1037.                         UpdateRgnSettings();
  1038.                         }
  1039.                     else {
  1040.                         SetPort(gWList[kDstWindow].window);
  1041.                         ResizeTestWindow(&oldDimen,kDstWindow);
  1042.                         }
  1043.                     }
  1044.                 }
  1045.                 
  1046.             SetPort(holdPort);
  1047.             bufferChanged = true;
  1048.             }
  1049.                 /*  Update the screen with the new changes  */
  1050.         if (bufferChanged || contentChanged)
  1051.             DrawBuffer(kBitWindow);
  1052.             for(i=kSrcWindow; i <= kBitWindow; i++)
  1053.                 DrawWindow(i);
  1054.         
  1055.         InitCursor();
  1056.         }
  1057.         
  1058.     return(okHit);
  1059. }
  1060.  
  1061.  
  1062. /*--------------------------------------------------------------------------------------*/
  1063. void  SelectFGColor (short theItem)
  1064. {
  1065.     register    i;
  1066.     RGBColor    tempRGB;
  1067.  
  1068.     if (theItem == kCustomColor)  {
  1069.         tempRGB = gFGColor.rgb;
  1070.         if (GetColor(gZeroPt,"\pSelect a foreground color.",&tempRGB,&tempRGB))  {
  1071.             for(i=kSrcWindow; i <= kDstWindow; i++)
  1072.                 DrawWindow(i);
  1073.  
  1074.             gFGColor.menuIndex     = kCustomColor;
  1075.             gFGColor.rgb        = tempRGB;
  1076.  
  1077.             DrawBuffer(kBitWindow);
  1078.             DrawWindow(kBitWindow);
  1079.             }
  1080.         }
  1081.     else  {
  1082.         gFGColor.menuIndex     = theItem;
  1083.         gFGColor.rgb        = gRGBArray[theItem-1];
  1084.  
  1085.         DrawBuffer(kBitWindow);
  1086.         DrawWindow(kBitWindow);
  1087.         }
  1088. }
  1089.  
  1090.  
  1091. /*--------------------------------------------------------------------------------------*/
  1092. void  SelectBKColor    (short theItem)
  1093. {
  1094.     register    i;
  1095.     RGBColor    tempRGB;
  1096.     
  1097.     if (theItem == kCustomColor)  {
  1098.         tempRGB = gBKColor.rgb;
  1099.         if (GetColor(gZeroPt,"\pSelect a background color.",&tempRGB,&tempRGB))  {
  1100.             for(i=kSrcWindow; i <= kDstWindow; i++)
  1101.                 DrawWindow(i);
  1102.  
  1103.             gBKColor.menuIndex     = kCustomColor;
  1104.             gBKColor.rgb        = tempRGB;
  1105.  
  1106.             DrawBuffer(kBitWindow);
  1107.             DrawWindow(kBitWindow);
  1108.             }
  1109.         }
  1110.     else  {
  1111.         gBKColor.menuIndex     = theItem;
  1112.         gBKColor.rgb        = gRGBArray[theItem-1];
  1113.  
  1114.         DrawBuffer(kBitWindow);
  1115.         DrawWindow(kBitWindow);
  1116.         }
  1117. }
  1118.  
  1119.  
  1120. /*--------------------------------------------------------------------------------------*/
  1121. void  SelectOPColor (short theItem)
  1122. {
  1123.     register    i;
  1124.     RGBColor    tempRGB;
  1125.  
  1126.  
  1127.     if (theItem == kCustomColor)  {
  1128.         tempRGB = gOPColor.rgb;
  1129.         if (GetColor(gZeroPt,"\pSelect an OpColor.",&tempRGB,&tempRGB))  {
  1130.             for(i=kSrcWindow; i <= kDstWindow; i++)
  1131.                 DrawWindow(i);
  1132.  
  1133.             gOPColor.menuIndex     = kCustomColor;
  1134.             gOPColor.rgb        = tempRGB;
  1135.  
  1136.             DrawBuffer(kBitWindow);
  1137.             DrawWindow(kBitWindow);
  1138.             }
  1139.         }
  1140.     else  {
  1141.         gOPColor.menuIndex     = theItem;
  1142.         gOPColor.rgb        = gRGBArray[theItem-1];
  1143.  
  1144.         DrawBuffer(kBitWindow);
  1145.         DrawWindow(kBitWindow);
  1146.         }
  1147. }
  1148.  
  1149.  
  1150. /*--------------------------------------------------------------------------------------*/
  1151. void  SelectHiliteColor    (short theItem)
  1152. {
  1153.     register    i;
  1154.     RGBColor    tempRGB;
  1155.  
  1156.  
  1157.     if (theItem == kCustomColor)  {
  1158.         tempRGB = gHiliteColor.rgb;
  1159.         if (GetColor(gZeroPt,"\pSelect a hilite color.",&tempRGB,&tempRGB))  {
  1160.             for(i=kSrcWindow; i <= kDstWindow; i++)
  1161.                 DrawWindow(i);
  1162.  
  1163.             gHiliteColor.menuIndex     = kCustomColor;
  1164.             gHiliteColor.rgb        = tempRGB;
  1165.  
  1166.             DrawBuffer(kBitWindow);
  1167.             DrawWindow(kBitWindow);
  1168.             }
  1169.         }
  1170.     else  {
  1171.         gHiliteColor.menuIndex     = theItem;
  1172.         gHiliteColor.rgb        = gRGBArray[theItem-1];
  1173.  
  1174.         DrawBuffer(kBitWindow);
  1175.         DrawWindow(kBitWindow);
  1176.         }
  1177. }
  1178.  
  1179.  
  1180. /*--------------------------------------------------------------------------------------*/
  1181. void  SelectRgn(short rgnCode, short rgnType)
  1182. {
  1183.  
  1184.     gRList[rgnCode].type = rgnType;
  1185.     
  1186.     if (rgnType == kNoRgn)  {
  1187.         if (gRList[rgnCode].rgn != nil)  {
  1188.             DisposeRgn(gRList[rgnCode].rgn);
  1189.             gRList[rgnCode].rgn = nil;
  1190.             }
  1191.         }
  1192.     else  {
  1193.         gRList[rgnCode].rgn = NewRgn();
  1194.         OpenRgn();
  1195.  
  1196.         switch(rgnType)  {
  1197.             case kDiamondClip:    DrawDiamond();        break;
  1198.             case kOvalClip:        DrawOval();            break;
  1199.             case kStarClip:        DrawStar();            break;
  1200.             case kHoleClip:        DrawHole();            break;
  1201.             }
  1202.  
  1203.         CloseRgn(gRList[rgnCode].rgn);
  1204.         }
  1205.     
  1206.     DrawBuffer(kBitWindow);
  1207.     DrawWindow(kBitWindow);
  1208. }
  1209.  
  1210.  
  1211. /*--------------------------------------------------------------------------------------*/
  1212. Boolean  SelectTrap()
  1213. /*
  1214. //    This call allows the user to select which of the two copymas traps he wishes to test. 
  1215. */
  1216. {
  1217.     DialogPtr    theDlog;
  1218.     GrafPtr        holdPort;
  1219.     short        itemHit;
  1220.     
  1221.     Boolean        okHit            = false;
  1222.     Boolean        done            = false;
  1223.     Boolean        bufferChanged    = false;
  1224.     Boolean        contentChanged    = false;
  1225.  
  1226.     short        tempTrapSelect   = gTrapSelect;
  1227.     
  1228.     register     i;
  1229.     Str255        tempStr;
  1230.     
  1231.     
  1232.  
  1233.                 /*  Allocate and center the dialog  */
  1234.     CenterWRsrc(DLOG,TrapDlogID,vThird);
  1235.     theDlog = GetNewDialog(TrapDlogID, nil, (WindowPtr)-1);
  1236.     
  1237.                 /*  If the dialog has been allocated successfully - process the user's selections  */
  1238.     if (theDlog != nil)  {
  1239.     
  1240.                 /*  Save off the current port.  */
  1241.         GetPort(&holdPort);
  1242.         SetPort(theDlog);
  1243.         
  1244.                 /*  Set up user item divider lines */
  1245.         SetDlogItemProc(theDlog,diTrapLine1,(ProcPtr)FrameDlogItemRect);
  1246.         SetDlogItemProc(theDlog,diTrapLine2,(ProcPtr)FrameDlogItemRect);
  1247.         
  1248.                 /*  Init the radio buttons to reflect current selection.  */
  1249.         HandleRadioButtons(theDlog,diCopyMaskButton,diCopyBitsButton,tempTrapSelect+diCopyMaskButton);
  1250.     
  1251.                 /*  Display the dialog  */
  1252.         ShowWindow(theDlog);
  1253.         
  1254.                 /*  Process the user's actions  */
  1255.         do  {
  1256.             ModalDialog((ProcPtr)HandleOkayCancel, &itemHit);
  1257.             
  1258.             switch (itemHit)  {
  1259.                     case  ok:                okHit = true;        
  1260.                     case  cancel:            done  = true;
  1261.                                             break;
  1262.                 
  1263.                     case  diCopyMaskButton:
  1264.                     case  diCopyDeepButton:
  1265.                     case  diCopyBitsButton: HandleRadioButtons(theDlog,diCopyMaskButton,diCopyBitsButton,itemHit);
  1266.                                             tempTrapSelect  = itemHit - diCopyMaskButton;
  1267.                                             break;
  1268.                     }
  1269.             }  while ( !done );
  1270.             
  1271.         DisposDialog(theDlog);
  1272.         SetPort(holdPort);
  1273.         }
  1274.         
  1275.     if ((okHit) && (gTrapSelect != tempTrapSelect))  {
  1276.         for(i=kSrcWindow; i <= kBitWindow; i++)
  1277.             DrawWindow(i);
  1278.             
  1279.         gTrapSelect = tempTrapSelect;
  1280.         GetIndString(&tempStr, kTitleStrings, gTrapSelect+4);
  1281.         SetWTitle(gWList[kBitWindow].window,tempStr); 
  1282.         
  1283.         ShowHide(gWList[kMskWindow].window, !(gTrapSelect==kCopyBits));
  1284.     
  1285.         DrawBuffer(kBitWindow);
  1286.         DrawWindow(kBitWindow);
  1287.         }
  1288.         
  1289.     return(okHit);
  1290. }
  1291.  
  1292.  
  1293. /*--------------------------------------------------------------------------------------*/
  1294. void  NeedSystem7Dlog()
  1295. /*
  1296. //    This dialog alerts the user that system 7.0 is needed for the app to run. 
  1297. */
  1298. {
  1299.     DialogPtr    theDlog;
  1300.     GrafPtr        holdPort;
  1301.     short        itemHit;
  1302.     Boolean        done        = false;
  1303.     
  1304.     
  1305.                 /*  Allocate and center the dialog  */
  1306.     CenterWRsrc(DLOG,Sys7DlogID,vThird);
  1307.     theDlog = GetNewDialog(Sys7DlogID, nil, (WindowPtr)-1);
  1308.     
  1309.                 /*  If the dialog has been allocated successfully - process the user's selections  */
  1310.     if (theDlog != nil)  {
  1311.     
  1312.                 /*  Save off the current port.  */
  1313.         GetPort(&holdPort);
  1314.         SetPort(theDlog);
  1315.  
  1316.         FrameDlogButton    (theDlog,ok);
  1317.             
  1318.                 /*  Display the dialog  */
  1319.         ShowWindow(theDlog);
  1320.         
  1321.                 /*  Process the user's actions  */
  1322.         do  {
  1323.         
  1324.             ModalDialog((ProcPtr)HandleOkayCancel, &itemHit);
  1325.             done = (itemHit == ok);     
  1326.                 
  1327.             }  while ( !done );
  1328.             
  1329.         DisposDialog(theDlog);
  1330.         SetPort(holdPort);
  1331.         }
  1332. }
  1333.  
  1334.  
  1335. /*--------------------------------------------------------------------------------------*/
  1336. void  AboutBitBlitz()
  1337.  
  1338.     DialogPtr    theDlog;
  1339.     GrafPtr        holdPort;
  1340.     short        itemHit;
  1341.     Boolean        done            = false;
  1342.  
  1343.  
  1344.  
  1345.     CenterWRsrc(DLOG,AboutBoxDlogID,vThird);
  1346.     theDlog = GetNewDialog(AboutBoxDlogID, nil, (WindowPtr)-1);
  1347.  
  1348.  
  1349.     if (theDlog != nil)  {
  1350.     
  1351.                 /*  Save off the current port.  */
  1352.         GetPort(&holdPort);
  1353.         SetPort(theDlog);
  1354.         
  1355.     
  1356.                 /*  Display the dialog  */
  1357.         ShowWindow(theDlog);
  1358.         
  1359.         
  1360.                 /*  Display about box until mouseDown  */
  1361.         do  {
  1362.             ModalDialog((ProcPtr)HandleOkayCancel, &itemHit);
  1363.             done  = (itemHit == 1);
  1364.             }  while ( !done );
  1365.             
  1366.             
  1367.             /*  Cleanup before returning  */
  1368.         DisposDialog(theDlog);
  1369.         SetPort(holdPort);
  1370.         }
  1371. }
  1372.  
  1373.  
  1374. /*======================================================================================*/
  1375. /*  Offscreen buffer imaging routines     */
  1376.  
  1377. /*--------------------------------------------------------------------------------------*/
  1378. void  FillSolid(RGBColor *theRGB, Rect *boundRect)
  1379. /*    
  1380. //    FillSolid() preserves and restores the current foreground color setting while filling
  1381. //    the specified Rect with the desired color.
  1382. */
  1383. {
  1384.     RGBColor    holdRGB;     
  1385.  
  1386.     GetForeColor(&holdRGB);
  1387.     
  1388.     RGBForeColor(theRGB);
  1389.     PaintRect(boundRect);
  1390.     
  1391.     RGBForeColor(&holdRGB);
  1392. }
  1393.  
  1394.  
  1395. /*--------------------------------------------------------------------------------------*/    
  1396. void  DoCopy()
  1397. /*    
  1398. //    DoCopy() updates the buffer associated with the copy window.  This update takes 
  1399. //    two steps.  Since the contents of the specified destination bitmap are overwritten by 
  1400. //  the copy result we keep both a destination window and the copy window.  Before performing 
  1401. //  the copy trap, the contents of the destination window's buffer are copied into the copy
  1402. //  window's buffer.  This buffer is then passed along with the source and mask window's buffers
  1403. //  to the copy routine.  
  1404. */
  1405. {
  1406.     GrafPtr            holdPort;
  1407.     GDHandle        holdDevice;
  1408.     BitMap            *srcBits, *mskBits, *dstBits;
  1409.     Rect            *srcRect, *mskRect, *dstRect;
  1410.     PixMapHandle    srcBuffer, mskBuffer, dstBuffer, bitBuffer;
  1411.  
  1412.  
  1413.             /*  If the user selects to use screen bits for the copy call the buffer pointer
  1414.             //  that is passed to the copy call is set to the window's portbits.
  1415.             */
  1416.     if (gUseScreenBits) {
  1417.         srcBits = &gWList[kSrcWindow].window->portBits;
  1418.         srcRect = &gWList[kSrcWindow].window->portRect;
  1419.  
  1420.         if (gWList[kMskWindow].bufferType == kBitMap) {
  1421.             mskBits = &gWList[kMskWindow].buffer.bitmap->portBits;
  1422.             mskRect = &gWList[kMskWindow].buffer.bitmap->portBits.bounds;
  1423.             }
  1424.         else  {
  1425.             mskBuffer  = GetGWorldPixMap(gWList[kMskWindow].buffer.gworld);
  1426.             LockPixels(mskBuffer);
  1427.             mskBits       = *mskBuffer;
  1428.             mskRect    = &gWList[kMskWindow].buffer.gworld->portRect;
  1429.             }
  1430.         
  1431.             /* The cursor is hidded during the copy so as not to interfere with the image  */
  1432.         HideCursor();
  1433.         }
  1434.         
  1435.             /* Otherwise, the offscreen gworld's portbits are passed  */
  1436.     else  {
  1437.         if (gWList[kSrcWindow].bufferType == kBitMap) {
  1438.             srcBits = &gWList[kSrcWindow].buffer.bitmap->portBits;
  1439.             srcRect = &gWList[kSrcWindow].buffer.bitmap->portBits.bounds;
  1440.             }
  1441.         else  {
  1442.             srcBuffer  = GetGWorldPixMap(gWList[kSrcWindow].buffer.gworld);
  1443.             LockPixels(srcBuffer);
  1444.             srcBits       = *srcBuffer;
  1445.             srcRect    = &gWList[kSrcWindow].buffer.gworld->portRect;
  1446.             }
  1447.  
  1448.         if (gWList[kMskWindow].bufferType == kBitMap) {
  1449.             mskBits = &gWList[kMskWindow].buffer.bitmap->portBits;
  1450.             mskRect = &gWList[kMskWindow].buffer.bitmap->portBits.bounds;
  1451.             }
  1452.         else  {
  1453.             mskBuffer  = GetGWorldPixMap(gWList[kMskWindow].buffer.gworld);
  1454.             LockPixels(mskBuffer);
  1455.             mskBits       = *mskBuffer;
  1456.             mskRect    = &gWList[kMskWindow].buffer.gworld->portRect;
  1457.             }
  1458.         }
  1459.  
  1460.     switch(gWList[kBitWindow].bufferType) {
  1461.         case kBitMap:    
  1462.             GetPort(&holdPort);
  1463.             SetPort(gWList[kBitWindow].buffer.bitmap);
  1464.             
  1465.             CopyBits(&gWList[kDstWindow].buffer.bitmap->portBits,            &gWList[kBitWindow].buffer.bitmap->portBits,
  1466.                      &gWList[kDstWindow].buffer.bitmap->portBits.bounds,       &gWList[kBitWindow].buffer.bitmap->portBits.bounds, srcCopy, NULL);
  1467.             
  1468.             if (gUseScreenBits) {
  1469.                 DrawWindow(kBitWindow);
  1470.                 dstBits = &gWList[kBitWindow].window->portBits;
  1471.                 dstRect = &gWList[kBitWindow].window->portRect;
  1472.                 }
  1473.             else  {
  1474.                 dstBits = &gWList[kBitWindow].buffer.bitmap->portBits;
  1475.                 dstRect = &gWList[kBitWindow].buffer.bitmap->portBits.bounds;
  1476.                 }
  1477.  
  1478.             SetEnv();
  1479.             if (gTrapSelect == kCopyMask)
  1480.                 CopyMask(srcBits, mskBits, dstBits, srcRect, mskRect, dstRect);
  1481.             else if (gTrapSelect == kCopyDeepMask) 
  1482.                 CopyMask2(srcBits, mskBits, dstBits, srcRect, mskRect, dstRect, gCopyMode, gRList[kMskRgn].rgn);
  1483.             else 
  1484.                 CopyBits (srcBits, dstBits, srcRect, dstRect, gCopyMode, gRList[kMskRgn].rgn);
  1485.             RestoreEnv();
  1486.                                               
  1487.             SetPort(holdPort);
  1488.             break;
  1489.             
  1490.         case kGWorld:
  1491.             dstBuffer = GetGWorldPixMap(gWList[kDstWindow].buffer.gworld);
  1492.             bitBuffer = GetGWorldPixMap(gWList[kBitWindow].buffer.gworld);
  1493.  
  1494.             LockPixels(dstBuffer);
  1495.             LockPixels(bitBuffer);
  1496.             
  1497.             GetGWorld(&(CGrafPtr)holdPort,&holdDevice);
  1498.             SetGWorld((CGrafPtr)gWList[kBitWindow].buffer.gworld,nil);
  1499.  
  1500.             CopyBits(*dstBuffer,                                   *bitBuffer,
  1501.                      &gWList[kDstWindow].buffer.gworld->portRect, &gWList[kBitWindow].buffer.gworld->portRect, srcCopy, nil);
  1502.  
  1503.             if (gUseScreenBits) {
  1504.                 SetGWorld((CGrafPtr)holdPort,holdDevice);
  1505.  
  1506.                 GetPort(&holdPort);
  1507.                 SetPort(gWList[kBitWindow].window);
  1508.  
  1509.                 DrawWindow(kBitWindow);
  1510.                 dstBits = &gWList[kBitWindow].window->portBits;
  1511.                 dstRect = &gWList[kBitWindow].window->portRect;
  1512.                 }
  1513.             else  {
  1514.                 dstBits = *bitBuffer;
  1515.                 dstRect = &gWList[kBitWindow].buffer.gworld->portRect;
  1516.                 }
  1517.  
  1518.             SetEnv();
  1519.             if (gTrapSelect == kCopyMask)
  1520.                 CopyMask(srcBits, mskBits, dstBits, srcRect, mskRect, dstRect);
  1521.             else if (gTrapSelect == kCopyDeepMask)
  1522.                 CopyMask2(srcBits, mskBits, dstBits, srcRect, mskRect, dstRect, gCopyMode, gRList[kMskRgn].rgn);
  1523.             else 
  1524.                 CopyBits (srcBits, dstBits, srcRect, dstRect,  gCopyMode, gRList[kMskRgn].rgn);
  1525.             RestoreEnv();
  1526.  
  1527.             if (gUseScreenBits) {
  1528.                 SetPort(holdPort);
  1529.                 
  1530.                 GetGWorld(&(CGrafPtr)holdPort,&holdDevice);
  1531.                 SetGWorld((CGrafPtr)gWList[kBitWindow].buffer.gworld,nil);
  1532.                 CopyBits(dstBits, *bitBuffer, dstRect, &gWList[kBitWindow].buffer.gworld->portRect, srcCopy, nil);
  1533.                 }
  1534.                          
  1535.             SetGWorld((CGrafPtr)holdPort,holdDevice);
  1536.             UnlockPixels(dstBuffer);
  1537.             UnlockPixels(bitBuffer);
  1538.             break;
  1539.         }
  1540.  
  1541.  
  1542.     if (gUseScreenBits) 
  1543.         ShowCursor();
  1544.     else {
  1545.         if (gWList[kSrcWindow].bufferType == kGWorld)
  1546.             UnlockPixels(srcBuffer);
  1547.  
  1548.         if (gWList[kMskWindow].bufferType == kGWorld)
  1549.             UnlockPixels(mskBuffer);
  1550.     
  1551.         }
  1552. }
  1553.  
  1554.  
  1555. /*--------------------------------------------------------------------------------------*/    
  1556. void  ImageBuffer(short windowCode)
  1557. /*
  1558. //    ImageBuffer() sets the current port in accordance with the buffer type, draws the image
  1559. //    designated by the contentType, and restores current port to its original setting.
  1560. */
  1561. {
  1562.     GrafPtr        holdPort;
  1563.     GDHandle    holdDevice;
  1564.     Rect        bufferRect;
  1565.  
  1566.  
  1567.     switch(gWList[windowCode].bufferType) {
  1568.         case kBitMap:    
  1569.             GetPort(&holdPort);
  1570.             SetPort(gWList[windowCode].buffer.bitmap);
  1571.             bufferRect = gWList[windowCode].buffer.bitmap->portBits.bounds;
  1572.             break;
  1573.             
  1574.         case kGWorld:
  1575.             LockPixels(GetGWorldPixMap(gWList[windowCode].buffer.gworld));
  1576.             GetGWorld(&holdPort,&holdDevice);
  1577.             SetGWorld(gWList[windowCode].buffer.gworld,nil);
  1578.             bufferRect = gWList[windowCode].buffer.gworld->portRect;
  1579.             break;
  1580.         }
  1581.             
  1582.     switch (gWList[windowCode].contentType)  {
  1583.         case kHLSRectBlend:      HLSRectBlend        (&bufferRect,gWList[windowCode].content.saturation); break;
  1584.         case kHLSHBlend:        HLSHLinearBlend        (&bufferRect,gWList[windowCode].content.saturation); break;
  1585.         case kHLSVBlend:        HLSVLinearBlend        (&bufferRect,gWList[windowCode].content.saturation); break;
  1586.         case kGrayRectBlend:    GrayRectBlend        (&bufferRect);                                         break;
  1587.         case kGrayHBlend:        GrayHLinearBlend    (&bufferRect);                                         break;
  1588.         case kGrayVBlend:        GrayVLinearBlend    (&bufferRect);                                         break;
  1589.         case kGrayPatRectBlend: GrayPatRectBlend    (&bufferRect);                                          break;
  1590.         case kGrayPatHBlend:    GrayPatHLinearBlend (&bufferRect);                                          break;
  1591.         case kGrayPatVBlend:    GrayPatVLinearBlend (&bufferRect);                                          break;
  1592.         case kSolidRGB:            FillSolid            (&gWList[windowCode].content.RGB,&bufferRect);         break;
  1593.         case kPICT:                if (gWList[windowCode].content.pictInfo != nil)
  1594.                                     DrawPicture(gWList[windowCode].content.pictInfo,&bufferRect);                        
  1595.                                     break;
  1596.         }
  1597.     
  1598.     switch(gWList[windowCode].bufferType) {
  1599.         case kBitMap:    SetPort  (holdPort);                
  1600.                         break;
  1601.         case kGWorld:    SetGWorld(holdPort,holdDevice);        
  1602.                         UnlockPixels(GetGWorldPixMap(gWList[windowCode].buffer.gworld));
  1603.                         break;
  1604.         }
  1605. }
  1606.  
  1607.  
  1608. /*--------------------------------------------------------------------------------------*/    
  1609. void  DrawBuffer(short windowCode)
  1610. /*    
  1611. //    DrawBuffer() redraws the specified window's offscreen buffer.
  1612. */
  1613. {    
  1614.     if (windowCode == kBitWindow) 
  1615.         DoCopy();
  1616.     else
  1617.         ImageBuffer(windowCode);
  1618. }
  1619.  
  1620.  
  1621.  
  1622. /*======================================================================================*/
  1623. /*  Offscreen-to-onscreen transferral     */
  1624.  
  1625. /*--------------------------------------------------------------------------------------*/
  1626. void  DrawWindow(short windowCode)
  1627. /*    
  1628. //    DrawWindow() draws the current contents of the specified window's buffer to that window.
  1629. */
  1630. {
  1631.     GrafPtr            holdPort;
  1632.     PixMapHandle    windowBuffer;
  1633.     
  1634.         
  1635.                 /*  Save the current port setting and set the current port to the specified window  */
  1636.     GetPort(&holdPort);
  1637.     SetPort(gWList[windowCode].window);
  1638.     
  1639.                 /*  Switch off the current buffer type setting to perform the appropriate copybits  */
  1640.     switch(gWList[windowCode].bufferType) {
  1641.         case kBitMap:    
  1642.             CopyBits(&gWList[windowCode].buffer.bitmap->portBits,            &gWList[windowCode].window->portBits,
  1643.                      &gWList[windowCode].buffer.bitmap->portBits.bounds,       &gWList[windowCode].window->portRect, srcCopy, NULL);
  1644.             break;
  1645.             
  1646.         case kGWorld:
  1647.             windowBuffer = GetGWorldPixMap(gWList[windowCode].buffer.gworld);
  1648.             LockPixels(windowBuffer);
  1649.             CopyBits(*windowBuffer,                               &gWList[windowCode].window->portBits,
  1650.                      &gWList[windowCode].buffer.gworld->portRect, &gWList[windowCode].window->portRect, srcCopy, NULL);
  1651.             UnlockPixels(windowBuffer);
  1652.             break;
  1653.         }
  1654.  
  1655.                 /*  Restore the current port to its original setting.  */
  1656.     SetPort(holdPort);
  1657. }
  1658.  
  1659.  
  1660.  
  1661. /*======================================================================================*/
  1662. /*  Window/Buffer resizing routines  */
  1663.  
  1664. /*--------------------------------------------------------------------------------------*/
  1665. Boolean  ResizeTestWindow(Point *newDimen, short windowCode)
  1666. /*    
  1667. //    ResizeWindow() sizes the specifed window to the new dimensions.
  1668. */
  1669. {
  1670.     Rect        tempRect, oldRect;
  1671.     Boolean        bufferScaled;
  1672.     GrafPtr        tempBits;
  1673.     GWorldFlags    gwError;
  1674.     
  1675.     
  1676.     switch(gWList[windowCode].bufferType) {
  1677.         case kBitMap:            
  1678.             oldRect  =  tempRect = gWList[windowCode].buffer.bitmap->portBits.bounds;
  1679.             tempRect.bottom       = tempRect.top  + newDimen->v;
  1680.             tempRect.right        = tempRect.left + newDimen->h;
  1681.     
  1682.             DisposeOSBitmap(gWList[windowCode].buffer.bitmap);
  1683.             
  1684.             bufferScaled     = CreateOSBitmap(&tempBits,&tempRect);
  1685.             if (bufferScaled)  
  1686.                 gWList[windowCode].buffer.bitmap = tempBits;
  1687.             else
  1688.                 CreateOSBitmap(&gWList[windowCode].buffer.bitmap,&oldRect);            
  1689.             break;
  1690.         
  1691.         case kGWorld:
  1692.             tempRect         = gWList[windowCode].buffer.gworld->portRect;
  1693.             tempRect.bottom  = tempRect.top  + newDimen->v;
  1694.             tempRect.right   = tempRect.left + newDimen->h;
  1695.             
  1696.             gwError          = UpdateGWorld(&gWList[windowCode].buffer.gworld, gWList[windowCode].bufferDepth, &tempRect, nil, nil, clipPix);
  1697.             bufferScaled     = ((gwError & gwFlagErr) == 0);
  1698.             break;
  1699.         }
  1700.  
  1701.     if (bufferScaled)  {
  1702.         if (windowCode != kBitWindow) 
  1703.             DrawBuffer(windowCode);
  1704.         }
  1705.     else
  1706.         OKRsrcAlert(kErrorStrings,kResizeMemErr);
  1707.         
  1708.     return(bufferScaled);
  1709. }
  1710.  
  1711.  
  1712.  
  1713. /*======================================================================================*/
  1714. /*  Test Window allocation/disposal routines  */
  1715.  
  1716.  
  1717. /*--------------------------------------------------------------------------------------*/    
  1718. void  CalcWindowRect(Rect *windowRect, short windowCode)
  1719. /*  
  1720. //  This procedure calculates the window rect for the window designated by windowCode.
  1721. //  It essentially divides the screen into 4 equal quadrants and insets the rect defining
  1722. //  the window's rect appropriately in order to have it positioned correctly on whatever
  1723. //  size screen the application is run.
  1724. */
  1725. {
  1726.     #define        kTitleBarHeight        20   
  1727.     #define        kWindowSep            10        /*  # pixels between windows and space between edge    */
  1728.                                             /*    of screen and window                              */
  1729.  
  1730.     Rect        screenRect;
  1731.     Point        windowCenter;
  1732.  
  1733.     screenRect = qd.screenBits.bounds;
  1734.     screenRect.top += MBarHeight;
  1735.  
  1736.     windowCenter.h    = screenRect.left  + (HRectLength(&screenRect) >> 1);
  1737.     windowCenter.v    = screenRect.top   + (VRectLength(&screenRect) >> 1);
  1738.     
  1739.     switch (windowCode)  {
  1740.         case kSrcWindow:
  1741.             SetRect(windowRect, screenRect.left+kWindowSep, 
  1742.                                 screenRect.top+kWindowSep+kTitleBarHeight, 
  1743.                                 windowCenter.h-(kWindowSep/2),  
  1744.                                 windowCenter.v-(kWindowSep/2));
  1745.             break;
  1746.             
  1747.         case kMskWindow:
  1748.             SetRect(windowRect, windowCenter.h+(kWindowSep/2),
  1749.                                 screenRect.top+kWindowSep+kTitleBarHeight,
  1750.                                 screenRect.right-kWindowSep,
  1751.                                 windowCenter.v-(kWindowSep/2));
  1752.             break;
  1753.             
  1754.         case kDstWindow:
  1755.             SetRect(windowRect, screenRect.left+kWindowSep,
  1756.                                 windowCenter.v+(kWindowSep/2)+kTitleBarHeight,
  1757.                                 windowCenter.h-(kWindowSep/2),
  1758.                                 screenRect.bottom-kWindowSep);
  1759.             break;
  1760.             
  1761.         case kBitWindow:
  1762.             SetRect(windowRect ,windowCenter.h+(kWindowSep/2),
  1763.                                 windowCenter.v+(kWindowSep/2)+kTitleBarHeight,
  1764.                                 screenRect.right-kWindowSep,
  1765.                                 screenRect.bottom-kWindowSep);
  1766.             break;
  1767.         }
  1768. }
  1769.  
  1770.  
  1771. /*--------------------------------------------------------------------------------------*/    
  1772. Boolean    CreateTestWindows()
  1773. {
  1774. /*  This function allocates, initializes, and displays the four test windows.  If an error 
  1775. //    occurs during this process and error message is displayed.  All memory allocated is 
  1776. //  disposed.  And false is returned so that the application will terminate from main. 
  1777. */  
  1778.     register    i;
  1779.     Rect        tempRect;
  1780.     Str255        title;
  1781.     
  1782.     
  1783.     for (i = kSrcWindow; i <= kBitWindow; i++)  {
  1784.         CalcWindowRect(&tempRect,i);
  1785.           GetIndString(&title, kTitleStrings, i+1);
  1786.  
  1787.         if (gColorAvail)
  1788.             gWList[i].window = NewCWindow(nil,&tempRect,title,true,documentProc,(WindowPtr)-1, false,0);
  1789.         else
  1790.             gWList[i].window = NewWindow(nil,&tempRect,title,true,documentProc,(WindowPtr)-1, false,0);
  1791.         if  (gWList[i].window == nil)
  1792.             goto handle_init_error;
  1793.             
  1794.         if  (!CreateWindowBuffer(i))
  1795.             goto handle_init_error;
  1796.         
  1797.         DrawBuffer(i);        
  1798.         DrawWindow(i);
  1799.         }
  1800.         
  1801.     return(true);
  1802.  
  1803.     handle_init_error:  DisposeTestWindows();
  1804.                         OKRsrcAlert(kErrorStrings,kBootMemErr);
  1805.                         return(false);
  1806. }
  1807.  
  1808.  
  1809. /*--------------------------------------------------------------------------------------*/
  1810. void    DisposeTestWindows()
  1811. /*
  1812. //    This procedure takes care of disposing all memory allocated in association with any 
  1813. //    of the app windows before the application quits either normally or in response to an
  1814. //  unrecoverable error.
  1815. */
  1816. {    
  1817.     register i;
  1818.     
  1819.     for (i = kSrcWindow; i <= kBitWindow; i++)  {
  1820.         if ((gWList[i].contentType == kPICT) && (gWList[i].content.pictInfo != nil))
  1821.             DisposHandle((Handle)gWList[i].content.pictInfo);
  1822.         DisposeWindowBuffer(i);    
  1823.         if (gWList[i].window != nil)
  1824.             DisposeWindow(gWList[i].window);
  1825.         }
  1826. }
  1827.